﻿////////////////////////////////////////////////////////////////////////////////////////////
// File: EffectParticle.cs                                                                //
// Author: Mike Binnix                                                                    //
// Desc: graphical particle with attributes and methods to modify and drag the apperence  //
//       of the particle to the screen.                                                   //
////////////////////////////////////////////////////////////////////////////////////////////

using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace SlothEngine.Physics.ParticleEffects
{
    public class EffectParticle : XNAParticle
    {
        #region Attribues
        protected Texture2D image;
        protected TimeSpan age;
        protected TimeSpan maxAge;
        protected float scale;
        protected float rotation;
        protected float alpha;
        protected Color color;
        protected Vector2 origin;
        protected TimeSpan startFadeIn;
        protected TimeSpan startFadeOut;
        protected TimeSpan fadeInDuration;
        protected TimeSpan fadeOutDuration;
        protected bool fadeIn;
        protected bool fadeOut;
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the particles image.
        /// </summary>
        public Texture2D Image
        {
            get
            {
                return image;
            }
            set
            {
                image = value;
            }
        }
        /// <summary>
        /// Gets the particles current age.
        /// </summary>
        public TimeSpan Age
        {
            get
            {
                return age;
            }
        }
        /// <summary>
        /// Gets or sets the particles maximum age.
        /// </summary>
        public TimeSpan MaxAge
        {
            get
            {
                return maxAge;
            }
            set
            {
                maxAge = value;
            }
        }
        /// <summary>
        /// Gets or sets the scale the particle should be drawn at between 0.0f and float.MaxValue.
        /// </summary>
        public float Scale
        {
            get
            {
                return scale;
            }
            set
            {
                if (value < 0.0f)
                    scale = 0.0f;
                else
                    scale = value;
            }
        }
        /// <summary>
        /// Gets or sets the image rotation.
        /// </summary>
        public float Rotation
        {
            get
            {
                return rotation;
            }
            set
            {
                rotation = value;
            }
        }
        /// <summary>
        /// Gets or sets the image alpha value between 0 and 255.
        /// </summary>
        public float Alpha
        {
            get
            {
                return alpha;
            }
            set
            {
                if (value < 0.0f)
                    alpha = 0.0f;
                else if (value > 255.0f)
                    alpha = 255.0f;
                else
                    alpha = value;
            }
        }
        /// <summary>
        /// Gets or sets the time that the particle should begin fading in
        /// </summary>
        public TimeSpan BeginFadeIn
        {
            get
            {
                return startFadeIn;
            }
            set
            {
                startFadeIn = value;
            }
        }
        /// <summary>
        /// Gets or sets the time that the particle should begin fading out.
        /// </summary>
        public TimeSpan BeginFadeOut
        {
            get
            {
                return startFadeOut;
            }
            set
            {
                startFadeOut = value;
            }
        }
        /// <summary>
        /// Gets or sets the amount of time left that the particle should fade in.
        /// </summary>
        public TimeSpan FadeInDuration
        {
            get
            {
                return fadeInDuration;
            }
            set
            {
                fadeInDuration = value;
            }
        }
        /// <summary>
        /// Gets or sets the amount of time left that the particle should fase out.
        /// </summary>
        public TimeSpan FadeOutDuration
        {
            get
            {
                return fadeOutDuration;
            }
            set
            {
                fadeOutDuration = value;
            }
        }
        /// <summary>
        /// Gets or sets the origin of the image.
        /// </summary>
        public Vector2 Origin
        {
            get
            {
                return origin;
            }
            set
            {
                origin = value;
            }
        }
        #endregion

        #region Constructors
        public EffectParticle()
            : base()
        {
            image = null;
            age = TimeSpan.Zero;
            maxAge = TimeSpan.MaxValue;
            scale = 1.0f;
            rotation = 0.0f;
            alpha = 255.0f;
            origin = Vector2.Zero;
            color = Color.White;
            startFadeIn = TimeSpan.Zero;
            startFadeOut = TimeSpan.Zero;
            fadeInDuration = TimeSpan.Zero;
            fadeOutDuration = TimeSpan.Zero;
            fadeIn = false;
            fadeOut = false;
        }
        public EffectParticle(float mass, float damping, Vector2 position, Vector2 velocity, Vector2 acceleration)
            : base(mass, damping, position, velocity, acceleration)
        {
            image = null;
            age = TimeSpan.Zero;
            maxAge = TimeSpan.MaxValue;
            scale = 1.0f;
            rotation = 0.0f;
            alpha = 255.0f;
            origin = Vector2.Zero;
            color = Color.White;
            startFadeIn = TimeSpan.Zero;
            startFadeOut = TimeSpan.Zero;
            fadeInDuration = TimeSpan.Zero;
            fadeOutDuration = TimeSpan.Zero;
            fadeIn = false;
            fadeOut = false;
        }
        public EffectParticle(float mass, float damping, Vector2 position, Vector2 velocity, Vector2 acceleration, Texture2D image, TimeSpan maxAge)
            : base(mass, damping, position, velocity, acceleration)
        {
            this.image = image;
            age = TimeSpan.Zero;
            this.maxAge = maxAge;
            scale = 1.0f;
            rotation = 0.0f;
            alpha = 255.0f;
            origin = Vector2.Zero;
            color = Color.White;
            startFadeIn = TimeSpan.Zero;
            startFadeOut = TimeSpan.Zero;
            fadeInDuration = TimeSpan.Zero;
            fadeOutDuration = TimeSpan.Zero;
            fadeIn = false;
            fadeOut = false;
        }
        public EffectParticle(float mass, float damping, Vector2 position, Vector2 velocity, Vector2 acceleration, Texture2D image, float rotation, float scale, float alpha, Color color, TimeSpan maxAge)
            : base(mass, damping, position, velocity, acceleration)
        {
            this.image = image;
            age = TimeSpan.Zero;
            this.maxAge = maxAge;
            this.scale = scale;
            this.rotation = rotation;
            this.alpha = alpha;
            origin = Vector2.Zero;
            this.color = color;
            startFadeIn = TimeSpan.Zero;
            startFadeOut = TimeSpan.Zero;
            fadeInDuration = TimeSpan.Zero;
            fadeOutDuration = TimeSpan.Zero;
            fadeIn = false;
            fadeOut = false;
        }
        public EffectParticle(float mass, float damping, Vector2 position, Vector2 velocity, Vector2 acceleration, Texture2D image, float rotation, float scale, float alpha, Color color, TimeSpan maxAge, TimeSpan beginFadeIn, TimeSpan fadeInDuration, TimeSpan beginFadeOut, TimeSpan fadeOutDuration)
            : base(mass, damping, position, velocity, acceleration)
        {
            this.image = image;
            age = TimeSpan.Zero;
            this.maxAge = maxAge;
            this.scale = scale;
            this.rotation = rotation;
            this.alpha = alpha;
            origin = Vector2.Zero;
            this.color = color;
            startFadeIn = beginFadeIn;
            startFadeOut = beginFadeOut;
            this.fadeInDuration = fadeInDuration;
            this.fadeOutDuration = fadeOutDuration;
            fadeIn = false;
            fadeOut = false;
        }
        #endregion

        #region Methods
        /// <summary>
        /// Updates the drawing and age information.  Sets destroy to true when particle should be removed from any managers.
        /// </summary>
        /// <param name="gameTime">Time since last update.</param>
        public override void Update(GameTime gameTime)
        {
            //update age and check if particle should be destroyed
            age = age + gameTime.ElapsedGameTime;
            if (age >= maxAge)
                destroy = true;

            // Reset fadng check
            fadeIn = false;
            fadeOut = false;

            if (age >= startFadeIn && age <= startFadeIn + fadeInDuration)
                fadeIn = true;

            if (age >= startFadeOut && age <= startFadeOut + fadeOutDuration)
                fadeOut = true;

            // Update image alpha and fade durations
            if (fadeIn || fadeOut)
            {
                float normalizedAge;
                if (fadeIn)
                {
                    normalizedAge = (float)age.TotalSeconds / ((float)startFadeIn.TotalSeconds + (float)fadeInDuration.TotalSeconds);
                    alpha = normalizedAge * 255;
                }
                else
                {
                    normalizedAge = (float)age.TotalSeconds / ((float)startFadeOut.TotalSeconds + (float)fadeOutDuration.TotalSeconds);
                    alpha = (1 - normalizedAge) * 255;
                }

                color.A = (byte)alpha;
            }

            base.Update(gameTime);
        }
        /// <summary>
        /// Draws the effect particle to the screen.
        /// </summary>
        /// <param name="spriteBatch"></param>
        public virtual void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(image, position, null, color, rotation, origin, scale, SpriteEffects.None, 0);
        }
        #endregion
    }
}
